﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using wcsServo.dao;
using wcsServo.domain;
using wcsServo.entity;

namespace wcsServo.service
{
    public class TaskService
    {
        private readonly object _lock = new object();
        /// <summary>
        /// 工位需要从空箱区搬送并创建任务
        /// </summary>
        /// <param name="stnNo"></param>
        /// <returns></returns>
        public ResultData_FUNC CreateTaskByKx(string stnNo)
        {
            ResultData_FUNC resultData = new ResultData_FUNC
            {
                Code = "0",
                Msg = "success",
                Writes = ""
            };
            try
            {
                lock (_lock)
                {
                    //检查一下空箱区是否有可用的空箱
                    string kxSql = $"select * from wcs_stn_mapping where status=2 and station_type='KX_HW' order by cont_type limit 1";
                    StnMapEntity kxStn = DBFactory.QueryFirst<StnMapEntity>(kxSql);
                    if (kxStn == null)
                    {
                        resultData.Code = "404";
                        resultData.Msg = $"线头工位[{stnNo}]所需空箱在空箱区无可用空箱!请核查!";
                        return resultData;
                    }
                    string frmPos = kxStn.WCS_STATION;
                    //根据空箱货位与线头工位获取对应的任务链
                    string routeSql = $"select * from wcs_route_set where frm_pos='{frmPos}' and to_pos='{stnNo}' limit 1";

                    RouteSetEntity routePath = DBFactory.QueryFirst<RouteSetEntity>(routeSql);
                    if (routePath == null)
                    {
                        resultData.Code = "create_kx_error_01";
                        resultData.Msg = $"空箱货位[{frmPos}]至线头工位[{stnNo}]未在wcs_route_set中配置搬送模板!请核查!";
                        return resultData;
                    }

                    //生成wcs_trk即可
                    TrkEntity wcsTrk = new TrkEntity
                    {
                        REQUEST_PK = DateTime.Now.ToString("yyyyMMddHHmmss"),
                        CONT_NO = kxStn.CONT_NO,
                        DVC_NO = routePath.DVC_NO,
                        TRK_TYPE = "03",
                        TRK_PRTY = "1",
                        FRM_POS = frmPos,
                        TO_POS = stnNo,
                        CUR_POS = frmPos,
                        CARRY_NO = routePath.CARRY_NO,
                        IS_FULL = "0",
                        GROUP_NO = "",
                        CREATOR = 1001,
                        CREATE_DATE = DateTime.Now
                    };

                    DBFactory.Insert2WcsTrk(wcsTrk);
                    //预分配站点状态
                    kxStn.STATUS = 1;
                    kxStn.COMMENTS = $"线头工位[{stnNo}]需求空箱,预分配";
                    kxStn.UPDATE_DATE = DateTime.Now;
                    DBFactory.UpdateStnMappingById(kxStn);
                    //任务创建成功需要给PLC确认信号
                    resultData.Msg = $"线头工位[{stnNo}]请求空箱成功!空箱位置[{frmPos}]";
                    return resultData;
                }
            }
            catch (Exception ex)
            {
                resultData.Code = "create_kx_error_500";
                resultData.Msg = $"线头工位{stnNo}请求空箱异常!causeBy:{ex.Message}";
                return resultData;
            }
        }

        /// <summary>
        /// 线头供应空箱至线尾
        /// </summary>
        /// <param name="stnNo"></param>
        /// <returns></returns>
        public ResultData_FUNC CreateTaskByXW(string stnNo, string value)
        {
            ResultData_FUNC resultData = new ResultData_FUNC
            {
                Code = "0",
                Msg = "success",
                Writes = ""
            };
            try
            {
                lock (_lock)
                {
                    //场景1：线头到线尾的搬送任务
                    if (value == "0")
                    {
                        //校验一下线头工位是否有空托盘
                        string itemSql = $"SELECT * FROM plc_item p LEFT JOIN wcs_stn_mapping w ON p.item_code=w.wcs_station WHERE item_grp = 'PLC_STATUS' AND item_value = '1' AND item_code IN ( 'XT1', 'XT2', 'XT3' ) AND w.status!='1' LIMIT 1";
                        PlcItemEntity xtItem = DBFactory.QueryFirst<PlcItemEntity>(itemSql);
                        if (xtItem == null)
                        {
                            resultData.Code = "404";
                            resultData.Msg = $"线尾工位[{stnNo}]需求空托盘!但线头工位尚无空托盘供应!请等待!";
                            return resultData;
                        }
                        string xtStnNo = xtItem.STN_NO;
                        //根据匹配到的线头工位,看一下对应工位信息（托盘条码）
                        string stnSql = $"select * from wcs_stn_mapping where wcs_station='{xtStnNo}'";
                        StnMapEntity xtStn = DBFactory.QueryFirst<StnMapEntity>(stnSql);
                        if (xtStn == null)
                        {
                            resultData.Code = "create_xw_error_02";
                            resultData.Msg = $"线尾工位[{xtStnNo}]未在[wcs_stn_mapping]中维护!请核查";
                            return resultData;
                        }
                        //根据线头工位与线尾工位获取场景路径
                        string pathSql = $"select * from wcs_route_set where frm_pos='{xtStnNo}' and to_pos='{stnNo}' limit 1";
                        RouteSetEntity routePath = DBFactory.QueryFirst<RouteSetEntity>(pathSql);
                        if (routePath == null)
                        {
                            resultData.Code = "create_xw_error_03";
                            resultData.Msg = $"线头工位[{xtStnNo}]至线头工位[{stnNo}]未在wcs_route_set中配置搬送模板!请核查!";
                            return resultData;
                        }
                        //生成wcs_trk即可
                        TrkEntity wcsTrk = new TrkEntity
                        {
                            REQUEST_PK = DateTime.Now.ToString("yyyyMMddHHmmss"),
                            CONT_NO = xtStn.CONT_NO,
                            DVC_NO = xtStn.DVC_NO,
                            TRK_TYPE = "03",
                            TRK_PRTY = "1",
                            FRM_POS = xtStnNo,
                            TO_POS = stnNo,
                            CUR_POS = xtStnNo,
                            CARRY_NO = routePath.CARRY_NO,
                            IS_FULL = "0",
                            GROUP_NO = "",
                            CREATOR = 1001,
                            CREATE_DATE = DateTime.Now
                        };

                        DBFactory.Insert2WcsTrk(wcsTrk);
                        //预分配站点状态
                        xtStn.STATUS = 1;
                        xtStn.COMMENTS = $"线尾工位[{stnNo}]需求空托盘,预分配";
                        xtStn.UPDATE_DATE = DateTime.Now;
                        DBFactory.UpdateStnMappingById(xtStn);
                        resultData.Msg = $"线尾工位[{stnNo}]请求成功,从线头工位[{xtStnNo}]搬送空托盘";
                    }
                    //成品下料场景
                    if (value == "2")
                    {
                        //检查一下当前成品是否有空闲的货位(需要考虑前后位置)
                        string cpSql = $"select * from wcs_stn_mapping where status=0 and station_type='CP_HW' order by wms_station,cont_type limit 1";
                        StnMapEntity cpStn = DBFactory.QueryFirst<StnMapEntity>(cpSql);
                        if (cpStn == null)
                        {
                            resultData.Code = "404";
                            resultData.Msg = $"线尾工位[{stnNo}]成品下料,暂无空闲成品货位!请等待!";
                            return resultData;
                        }
                        string toPos = cpStn.WCS_STATION;
                        //根据线尾工位到成品货位获取场景路径
                        string pathSql = $"select * from wcs_route_set where frm_pos='{stnNo}' and to_pos='{toPos}' limit 1";
                        RouteSetEntity routePath = DBFactory.QueryFirst<RouteSetEntity>(pathSql);
                        if (routePath == null)
                        {
                            resultData.Code = "create_xw_error_05";
                            resultData.Msg = $"线尾工位[{stnNo}]至成品货位[{toPos}]未在wcs_route_set中配置搬送模板!请核查!";
                            return resultData;
                        }

                        //根据匹配到的线尾工位,看一下对应工位信息（托盘条码）
                        string stnSql = $"select * from wcs_stn_mapping where wcs_station='{stnNo}'";
                        StnMapEntity xwStn = DBFactory.QueryFirst<StnMapEntity>(stnSql);
                        if (xwStn == null)
                        {
                            resultData.Code = "create_xw_error_02";
                            resultData.Msg = $"线尾工位[{stnNo}]未在[wcs_stn_mapping]中维护!请核查";
                            return resultData;
                        }
                        string contNo = xwStn.CONT_NO;

                        //生成wcs_trk即可
                        TrkEntity wcsTrk = new TrkEntity
                        {
                            REQUEST_PK = DateTime.Now.ToString("yyyyMMddHHmmss"),
                            CONT_NO = contNo,
                            DVC_NO = cpStn.DVC_NO,
                            TRK_TYPE = "03",
                            TRK_PRTY = "1",
                            FRM_POS = stnNo,
                            TO_POS = toPos,
                            CUR_POS = stnNo,
                            CARRY_NO = routePath.CARRY_NO,
                            IS_FULL = "0",
                            GROUP_NO = "",
                            CREATOR = 1001,
                            CREATE_DATE = DateTime.Now
                        };

                        DBFactory.Insert2WcsTrk(wcsTrk);
                        //预分配站点状态
                        cpStn.STATUS = 1;
                        cpStn.COMMENTS = $"线尾工位[{stnNo}]成品下料,预分配";
                        cpStn.UPDATE_DATE = DateTime.Now;
                        DBFactory.UpdateStnMappingById(cpStn);
                        resultData.Msg = $"线尾工位[{stnNo}]下料成功,目标成品货位[{toPos}]";
                    }

                    return resultData;
                }
            }
            catch (Exception ex)
            {
                resultData.Code = "create_xw_error_500";
                resultData.Msg = $"线尾工位{stnNo}信号[{value}]请求异常!causeBy:{ex.Message}";
                return resultData;
            }
        }
    }
}
